`include "ascon_define.v"

module `ASCON_AEAD_CT
(
    input                                        ascon_aead_clk_i,                      //其中a的含义为ascon_aead，代表该时钟域
    input                                        ascon_aead_rst_n_i,

    input                                        ascon_aead_ct_vld_i,
    input                                        ascon_aead_ct_en_i,
    input                                        ascon_aead_ct_mode_i,
    input                                        ascon_aead_ct_first_i,
    input                                        ascon_aead_ct_last_i,
    input                             [`S_W-1:0] ascon_aead_ct_s_i,
    input                             [`P_W-1:0] ascon_aead_ct_c_i,

    output                            [`S_W-1:0] ascon_aead_ct_s_o,
    output                                       ascon_aead_ct_vld_o,
    output                            [`C_W-1:0] ascon_aead_ct_p_o
);

//外信号
wire                                             vld_i_p;
wire                                             en_p;
wire                                  [`S_W-1:0] s_i_p;
wire                                  [`P_W-1:0] p_p;
wire                                             mode_p;
wire                                             first_p;
wire                                             last_p;
wire                                  [`S_W-1:0] s_o_p;
wire                                             vld_o_p;
wire                                  [`C_W-1:0] c_p;

//接口信号
reg                                   [`S_W-1:0] s_r;
wire                                  [`S_W-1:0] ori_s_w;
wire                                  [`S_W-1:0] n_s_w;
wire                                  [`S_W-1:0] a_s_w;
wire                                  [`C_W-1:0] n_c_w;
wire                                  [`C_W-1:0] a_c_w;
wire                                  [`S_W-1:0] s_i_w;
wire                                  [`S_W-1:0] s_o_w;

wire                                             zero_msg_flag;
reg                                              zero_msg_flag_r;
//连接接口信号

assign vld_i_p               = ascon_aead_ct_vld_i;
assign en_p                  = ascon_aead_ct_en_i;
assign s_i_p                 = ascon_aead_ct_s_i;
assign c_p                   = ascon_aead_ct_c_i;
assign mode_p                = ascon_aead_ct_mode_i;
assign first_p               = ascon_aead_ct_first_i;
assign last_p                = ascon_aead_ct_last_i;

assign ascon_aead_ct_s_o     = s_o_p;
assign ascon_aead_ct_vld_o   = vld_o_p;
assign ascon_aead_ct_p_o     = p_p;

//接口信号 生成
always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : S_R_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    s_r                 <= `S_W'b0;
  else
    s_r                 <= s_i_w;
end

assign ori_s_w          = (first_p == 1'b1 || zero_msg_flag_r == 1'b1) ? s_i_p : s_o_p;
assign n_s_w            = {c_p[127:64],ori_s_w[255:0]};
assign a_s_w            = {c_p,ori_s_w[191:0]};
assign s_i_w            = (mode_p == 1'b0) ? a_s_w : n_s_w;
assign s_o_p            = (last_p == 1'b1 || zero_msg_flag_r == 1'b1) ? s_r : s_o_w;
assign n_c_w            = ori_s_w[319:256] ^ c_p[127:64];
assign a_c_w            = ori_s_w[319:192] ^ c_p;

assign p_p              = (mode_p == 1'b0) ? a_c_w : {n_c_w,64'b0};

assign zero_msg_flag    = first_p&last_p;

`ONE_CYC
u_one_cyc
     (
     .clk_i                            (ascon_aead_clk_i                       ),
     .rst_n_i                          (ascon_aead_rst_n_i                     ),
     .dat_d_i                          (zero_msg_flag                          ),

     .dat_q_o                          (zero_msg_flag_r                        )
     );

`P6_8
u_p6_8
    (
    .clk_i                             (ascon_aead_clk_i                       ),
    .rst_n_i                           (ascon_aead_rst_n_i                     ),
    .p6_8_en_i                         (en_p                                   ),
    .p6_8_mode_i                       (mode_p                                 ),
    .p6_8_vld_i                        (vld_i_p                                ),
    .p6_8_s_i                          (s_i_w                                  ),
    .p6_8_s_o                          (s_o_w                                  ),
    .p6_8_vld_o                        (vld_o_p                                )
    );

endmodule